from flask import Blueprint, jsonify, request, send_from_directory, current_app
from app.models import Carousel, Service, ServiceCategory, ServiceProvider, Rating
from app import db
from app.schemas import (
    CarouselSchema,
    ServiceSchema,
    ServiceCategorySchema,
    ServiceProviderSchema,
    RatingSchema
)
from flask_jwt_extended import jwt_required, get_jwt_identity
from app.utils import save_image, allowed_file
import os

bp = Blueprint('main', __name__)

@bp.route('/', methods=['GET'])
def index():
    # Get carousel images
    carousel_images = Carousel.query.order_by(Carousel.created_at.desc()).limit(5).all()
    
    # Get featured service categories
    categories = ServiceCategory.query.all()
    
    # Get featured service providers
    featured_providers = ServiceProvider.query.limit(6).all()
    
    return jsonify({
        'status': 'success',
        'data': {
            'carousel': CarouselSchema(many=True).dump(carousel_images),
            'categories': ServiceCategorySchema(many=True).dump(categories),
            'featured_providers': ServiceProviderSchema(many=True).dump(featured_providers)
        }
    })

@bp.route('/services', methods=['GET', 'POST'])
def services():
    if request.method == 'GET':
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('page_size', 10, type=int)
        category_id = request.args.get('category', type=int)
        search = request.args.get('search', '')
        
        # Base query
        query = Service.query
        
        # Apply filters
        if category_id:
            query = query.filter_by(category_id=category_id)
        if search:
            query = query.filter(Service.title.ilike(f'%{search}%'))
        
        # Get paginated results
        pagination = query.order_by(Service.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'status': 'success',
            'data': {
                'items': ServiceSchema(many=True).dump(pagination.items),
                'pagination': {
                    'page': pagination.page,
                    'pages': pagination.pages,
                    'per_page': pagination.per_page,
                    'total': pagination.total,
                    'has_next': pagination.has_next,
                    'has_prev': pagination.has_prev
                }
            }
        })
    elif request.method == 'POST':
        try:
            # 支持 JSON 格式的请求
            if request.is_json:
                data = request.get_json()
            # 支持表单格式的请求（带文件上传）
            else:
                data = request.form
                # 处理图片文件
                image = request.files.get('image')
                if image:
                    data = dict(data)  # 转换为可修改的字典
                    data['image_url'] = save_image(image, 'services')

            # 创建服务对象
            service = Service(
                title=data.get('title', '未命名服务'),
                description=data.get('description', ''),
                provider_id=data.get('provider_id'),
                category_id=data.get('category_id'),
                image_url=data.get('image_url'),
                video_url=data.get('video_url', ''),
                audio_url=data.get('audio_url', '')
            )

            # 如果提供了 provider_id，验证其存在性
            if service.provider_id and not ServiceProvider.query.get(service.provider_id):
                return jsonify({
                    'status': 'error',
                    'message': 'Invalid provider_id'
                }), 400

            # 如果提供了 category_id，验证其存在性
            if service.category_id and not ServiceCategory.query.get(service.category_id):
                return jsonify({
                    'status': 'error',
                    'message': 'Invalid category_id'
                }), 400

            db.session.add(service)
            db.session.commit()

            return jsonify({
                'status': 'success',
                'message': 'Service created successfully',
                'data': ServiceSchema().dump(service)
            }), 201

        except Exception as e:
            db.session.rollback()
            print("Error creating service:", str(e))
            return jsonify({
                'status': 'error',
                'message': f'Error creating service: {str(e)}'
            }), 400

@bp.route('/services/<int:id>', methods=['GET', 'PUT', 'DELETE'])
def service_detail(id):
    if request.method == 'DELETE':
        try:
            service = Service.query.get_or_404(id)
            db.session.delete(service)
            db.session.commit()
            
            return jsonify({
                'status': 'success',
                'message': f'Service {id} deleted successfully'
            })
        except Exception as e:
            db.session.rollback()
            return jsonify({
                'status': 'error',
                'message': f'Error deleting service: {str(e)}'
            }), 500
    
    service = Service.query.get_or_404(id)
    
    # Get service ratings
    ratings = Rating.query.filter_by(provider_id=service.provider_id)\
        .order_by(Rating.created_at.desc()).all()
    
    # Calculate average rating
    avg_rating = 0
    if ratings:
        avg_rating = sum(r.rating for r in ratings) / len(ratings)
    
    # Get related services from same category
    related_services = Service.query\
        .filter(Service.category_id == service.category_id)\
        .filter(Service.id != service.id)\
        .limit(3).all()
    
    return jsonify({
        'status': 'success',
        'data': {
            'service': ServiceSchema().dump(service),
            'ratings': RatingSchema(many=True).dump(ratings),
            'avg_rating': round(avg_rating, 1),
            'related_services': ServiceSchema(many=True).dump(related_services)
        }
    })

@bp.route('/categories', methods=['GET', 'POST'])
def category_detail(id):
    category = ServiceCategory.query.get_or_404(id)
    
    # Get providers in this category
    providers = ServiceProvider.query.filter_by(category_id=id).all()
    
    # Get services in this category
    services = Service.query.filter_by(category_id=id)\
        .order_by(Service.created_at.desc()).all()
    
    return jsonify({
        'status': 'success',
        'data': {
            'category': ServiceCategorySchema().dump(category),
            'providers': ServiceProviderSchema(many=True).dump(providers),
            'services': ServiceSchema(many=True).dump(services)
        }
    })

@bp.route('/providers', methods=['GET', 'POST'])
def provider_detail(id):
    provider = ServiceProvider.query.get_or_404(id)
    
    # Get provider's services
    services = Service.query.filter_by(provider_id=id)\
        .order_by(Service.created_at.desc()).all()
    
    # Get provider's ratings
    ratings = Rating.query.filter_by(provider_id=id)\
        .order_by(Rating.created_at.desc()).all()
    
    # Calculate average rating
    avg_rating = 0
    if ratings:
        avg_rating = sum(r.rating for r in ratings) / len(ratings)
    
    return jsonify({
        'status': 'success',
        'data': {
            'provider': ServiceProviderSchema().dump(provider),
            'services': ServiceSchema(many=True).dump(services),
            'ratings': RatingSchema(many=True).dump(ratings),
            'avg_rating': round(avg_rating, 1)
        }
    })

@bp.route('/ratings', methods=['GET', 'POST'])
def ratings():
    if request.method == 'GET':
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('page_size', 10, type=int)
        search = request.args.get('search', '')
        
        # Base query
        query = Rating.query
        
        # Apply filters
        if search:
            query = query.filter(Rating.comment.ilike(f'%{search}%'))
        
        # Get paginated results
        pagination = query.order_by(Rating.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'status': 'success',
            'data': {
                'items': RatingSchema(many=True).dump(pagination.items),
                'pagination': {
                    'page': pagination.page,
                    'pages': pagination.pages,
                    'per_page': pagination.per_page,
                    'total': pagination.total,
                    'has_next': pagination.has_next,
                    'has_prev': pagination.has_prev
                }
            }
        })
    elif request.method == 'POST':
        try:
            data = request.get_json()
            rating = Rating(
                rating=data['rating'],
                comment=data.get('comment', ''),
                provider_id=data['provider_id'],
                user_id=data['user_id']
            )
            db.session.add(rating)
            db.session.commit()
            return jsonify({
                'status': 'success',
                'message': 'Rating created successfully',
                'data': RatingSchema().dump(rating)
            }), 201
        except Exception as e:
            db.session.rollback()
            return jsonify({
                'status': 'error',
                'message': str(e)
            }), 400

@bp.route('/ratings/<int:id>', methods=['GET', 'DELETE'])
def rating_detail(id):
    rating = Rating.query.get_or_404(id)
    
    return jsonify({
        'status': 'success',
        'data': {
            'rating': RatingSchema().dump(rating)
        }
    })

@bp.route('/carousel', methods=['GET', 'POST'])
def carousel():
    if request.method == 'GET':
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('page_size', 10, type=int)
        
        # Get paginated results
        pagination = Carousel.query.order_by(Carousel.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'status': 'success',
            'data': {
                'items': CarouselSchema(many=True).dump(pagination.items),
                'pagination': {
                    'page': pagination.page,
                    'pages': pagination.pages,
                    'per_page': pagination.per_page,
                    'total': pagination.total,
                    'has_next': pagination.has_next,
                    'has_prev': pagination.has_prev
                }
            }
        })
    elif request.method == 'POST':
        try:
            data = request.get_json()
            
            # 只检查必需字段
            if not data or 'image_url' not in data:
                return jsonify({
                    'status': 'error',
                    'message': 'Image URL is required'
                }), 400
            
            carousel = Carousel(
                image_url=data['image_url'],
                link=data.get('link', '')  # link 是可选的
            )
            
            db.session.add(carousel)
            db.session.commit()
            
            return jsonify({
                'status': 'success',
                'message': 'Carousel created successfully',
                'data': CarouselSchema().dump(carousel)
            }), 201
            
        except Exception as e:
            db.session.rollback()
            return jsonify({
                'status': 'error',
                'message': str(e)
            }), 400

@bp.route('/carousel/<int:id>', methods=['GET', 'PUT', 'DELETE'])
def carousel_detail(id):
    carousel = Carousel.query.get_or_404(id)
    
    if request.method == 'GET':
        return jsonify({
            'status': 'success',
            'data': CarouselSchema().dump(carousel)
        })
    
    elif request.method == 'PUT':
        try:
            data = request.get_json()
            
            # 更新字段
            if 'image_url' in data:
                carousel.image_url = data['image_url']
            if 'link' in data:
                carousel.link = data['link']
            
            db.session.commit()
            
            return jsonify({
                'status': 'success',
                'message': 'Carousel updated successfully',
                'data': CarouselSchema().dump(carousel)
            })
            
        except Exception as e:
            db.session.rollback()
            return jsonify({
                'status': 'error',
                'message': str(e)
            }), 400
            
    elif request.method == 'DELETE':
        try:
            db.session.delete(carousel)
            db.session.commit()
            
            return jsonify({
                'status': 'success',
                'message': f'Carousel {id} deleted successfully'
            })
            
        except Exception as e:
            db.session.rollback()
            return jsonify({
                'status': 'error',
                'message': str(e)
            }), 400

# 修改静态文件服务路由
@bp.route('/uploads/<path:filename>')
def uploaded_file(filename):
    return send_from_directory(current_app.config['UPLOAD_FOLDER'], filename)

# 添加文件上传接口
@bp.route('/upload', methods=['POST'])
def upload_file():
    """上传文件接口"""
    try:
        if 'file' not in request.files:
            return jsonify({
                'status': 'error',
                'message': 'No file part'
            }), 400
            
        file = request.files['file']
        folder = request.form.get('folder', 'images')  # 可以指定保存的子文件夹
        
        if file.filename == '':
            return jsonify({
                'status': 'error',
                'message': 'No selected file'
            }), 400
            
        if file and allowed_file(file.filename):
            file_url = save_image(file, folder)
            return jsonify({
                'status': 'success',
                'message': 'File uploaded successfully',
                'data': {
                    'url': file_url
                }
            }), 201
        else:
            return jsonify({
                'status': 'error',
                'message': f'Invalid file type. Allowed types are: {", ".join(ALLOWED_EXTENSIONS)}'
            }), 400
            
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500 